home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 10868 / 10868.xpi / chrome / sync.jar / content / sync.js < prev    next >
Text File  |  2010-02-02  |  15KB  |  391 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Bookmarks Sync.
  15.  *
  16.  * The Initial Developer of the Original Code is Mozilla.
  17.  * Portions created by the Initial Developer are Copyright (C) 2007
  18.  * the Initial Developer. All Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *  Dan Mills <thunder@mozilla.com>
  22.  *  Chris Beard <cbeard@mozilla.com>
  23.  *  Dan Mosedale <dmose@mozilla.org>
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the MPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the MPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. if (typeof(Cc) == "undefined")
  40.   var Cc = Components.classes;
  41. if (typeof(Ci) == "undefined")
  42.   var Ci = Components.interfaces;
  43. if (typeof Cu == "undefined")
  44.   var Cu = Components.utils;
  45. if (typeof Cr == "undefined")
  46.   var Cr = Components.results;
  47.  
  48. function WeaveWindow() {
  49.   if (window.location.href != getBrowserURL())
  50.     return;
  51.  
  52.   let obs = [["weave:service:sync:start", "onSyncStart"],
  53.     ["weave:service:sync:finish", "onSyncFinish"],
  54.     ["weave:service:sync:error", "onSyncError"],
  55.     ["weave:service:sync:delayed", "onSyncDelay"],
  56.     ["weave:engine:sync:start",  "onEngineStart"],
  57.     ["weave:service:verify-login:start", "onLoginStart"],
  58.     ["weave:service:login:finish", "onLoginFinish"],
  59.     ["weave:service:login:error", "onLoginError"],
  60.     ["weave:service:logout:finish", "onLogout"],
  61.     ["private-browsing", "onPrivateBrowsingChange"],
  62.     ["weave:notification:added", "onNotificationAdded"],
  63.     ["weave:notification:removed", "onNotificationRemoved"]];
  64.  
  65.   // Add the observers now and remove them on unload
  66.   let weaveWin = this;
  67.   let addRem = function(add) obs.forEach(function([topic, func])
  68.     Weave.Svc.Obs[add ? "add" : "remove"](topic, weaveWin[func], weaveWin));
  69.   addRem(true);
  70.   window.addEventListener("unload", function() addRem(false), false);
  71.  
  72.   if (Weave.Svc.Prefs.get("lastversion") == "firstrun") {
  73.     setTimeout(this.openPrefs, 500);
  74.     Weave.Svc.Prefs.set("lastversion", Weave.WEAVE_VERSION);
  75.  
  76.   } else if (Weave.Svc.Prefs.get("lastversion") != Weave.WEAVE_VERSION) {
  77.     let url = "https://services.mozilla.com/sync/updated/?version=" +
  78.       Weave.WEAVE_VERSION;
  79.     setTimeout(function() { window.openUILinkIn(url, "tab"); }, 500);
  80.     Weave.Svc.Prefs.set("lastversion", Weave.WEAVE_VERSION);
  81.   }
  82.  
  83.   // TODO: This is a fix for the general case of bug 436936.  It will
  84.   // not support marginal cases such as when a new browser window is
  85.   // opened in the middle of signing-in or syncing.
  86.   if (Weave.Svc.Private.privateBrowsingEnabled)
  87.     this._setStatus("privateBrowsing");
  88.   else if (Weave.Service.isLoggedIn)
  89.     this.onLoginFinish();
  90.   else
  91.     this._setStatus("offline");
  92. }
  93. WeaveWindow.prototype = {
  94.   get _isTopBrowserWindow() {
  95.     // TODO: This code is mostly just a workaround that ensures that only one
  96.     // browser window ever performs any actions that are meant to only
  97.     // be performed once in response to a weave event.  Ideally, such code
  98.     // should not be handled by browser windows, but instead by e.g. actual
  99.     // singleton services.
  100.     var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  101.                        .getService(Components.interfaces.nsIWindowMediator);
  102.     var win = wm.getMostRecentWindow("navigator:browser");
  103.     return (win == window);
  104.   },
  105.  
  106.   get _stringBundle() {
  107.     let stringBundle = document.getElementById("weaveStringBundle");
  108.     this.__defineGetter__("_stringBundle",
  109.                           function() { return stringBundle; });
  110.     return this._stringBundle;
  111.   },
  112.  
  113.   _setStatus: function WeaveWin_setStatus(status) {
  114.     let label;
  115.     switch (status) {
  116.       case "offline":
  117.         label = this._stringBundle.getString("status.offline");
  118.         break;
  119.       case "privateBrowsing":
  120.         label = this._stringBundle.getString("status.privateBrowsing");
  121.         break;
  122.       default:
  123.         label = Weave.Service.username;
  124.     }
  125.  
  126.     let button = document.getElementById("sync-menu-button");
  127.     button.setAttribute("label", label);
  128.     button.setAttribute("image", "chrome://weave/skin/" + (status == "active" ?
  129.       "sync-throbber-16x16-active.apng" : "sync-16x16.png"));
  130.   },
  131.  
  132.   onLoginStart: function WeaveWin_onLoginStart() {
  133.     this._setStatus("active");
  134.   },
  135.  
  136.   onLoginError: function WeaveWin_onLoginError() {
  137.     this._setStatus("offline");
  138.  
  139.     // Don't notify on missing passphrase errors
  140.     if (!Weave.Service.passphrase)
  141.       return;
  142.  
  143.     let title = this._stringBundle.getString("error.login.title");
  144.     let reason = Weave.Utils.getErrorString(Weave.Status.login);
  145.     let description =
  146.       this._stringBundle.getFormattedString("error.login.description", [reason]);
  147.  
  148.     let notification = new Weave.Notification(title, description, null,
  149.                                               Weave.Notifications.PRIORITY_WARNING);
  150.     Weave.Notifications.replaceTitle(notification);
  151.   },
  152.  
  153.   onLoginFinish: function WeaveWin_onLoginFinish() {
  154.     this._setStatus("idle");
  155.  
  156.     // Clear out any login failure notifications
  157.     let title = this._stringBundle.getString("error.login.title");
  158.     Weave.Notifications.removeAll(title);
  159.   },
  160.  
  161.   onLogout: function WeaveWin_onLogout() {
  162.     this._setStatus("offline");
  163.   },
  164.  
  165.   onPrivateBrowsingChange: function WeaveWin_onPrivateBrowsingChange(subject, data) {
  166.     if (data == "enter")
  167.       this._setStatus("privateBrowsing");
  168.     else if (Weave.Service.isLoggedIn)
  169.       this._setStatus("idle");
  170.     else
  171.       this._setStatus("offline");
  172.   },
  173.  
  174.   _allowSBUpdates: false,
  175.   onSyncStart: function WeaveWin_onSyncStart() {
  176.     this._setStatus("active");
  177.     this._allowSBUpdates = true;
  178.   },
  179.  
  180.   _onSyncEnd: function WeaveWin__onSyncEnd(status) {
  181.     this._allowSBUpdates = false;
  182.     this._setStatus("idle");
  183.  
  184.     let title = this._stringBundle.getString("error.sync.title");
  185.     if (!status) {
  186.       let error = Weave.Utils.getErrorString(Weave.Status.sync);
  187.       let description = this._stringBundle
  188.                             .getFormattedString("error.sync.description", [error]);
  189.  
  190.       let priority = Weave.Notifications.PRIORITY_WARNING;
  191.       let buttons = [];
  192.       if (Weave.Status.sync == Weave.VERSION_OUT_OF_DATE) {
  193.         description = Weave.Str.sync.get("error.sync.needUpdate.description");
  194.         let label = Weave.Str.sync.get("error.sync.needUpdate.label");
  195.         let accesskey = Weave.Str.sync.get("error.sync.needUpdate.accesskey");
  196.         buttons.push(new Weave.NotificationButton(label, accesskey, function() {
  197.           let theEM = Weave.Svc.WinMediator.getMostRecentWindow("Extension:Manager");
  198.           if (theEM != null) {
  199.             theEM.focus();
  200.             theEM.showView("extensions");
  201.           }
  202.           else {
  203.             const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
  204.             const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
  205.             window.openDialog(EMURL, "", EMFEATURES, "extensions");
  206.           }
  207.           return true;
  208.         }));
  209.       }
  210.       else if (!Weave.Status.enforceBackoff) {
  211.         priority = Weave.Notifications.PRIORITY_INFO;
  212.         buttons.push(new Weave.NotificationButton(
  213.           this._stringBundle.getString("error.sync.tryAgainButton.label"),
  214.           this._stringBundle.getString("error.sync.tryAgainButton.accesskey"),
  215.           function() { gWeaveWin.doSync(); return true; }
  216.         ));
  217.       }
  218.  
  219.       let notification =
  220.         new Weave.Notification(title, description, null, priority, buttons);
  221.       Weave.Notifications.replaceTitle(notification);
  222.     }
  223.     // Clear out sync failures on a successful sync
  224.     else
  225.       Weave.Notifications.removeAll(title);
  226.  
  227.     if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
  228.       title = this._stringBundle.getString("error.sync.no_node_found.title");
  229.       Weave.Notifications.removeAll(title);
  230.       this._wasDelayed = false;
  231.     }
  232.  
  233.     this._updateLastSyncItem();
  234.   },
  235.  
  236.   onSyncFinish: function WeaveWin_onSyncFinish(subject, data) {
  237.     this._onSyncEnd(true);
  238.   },
  239.  
  240.   onSyncError: function WeaveWin_onSyncError(subject, data) {
  241.     this._onSyncEnd(false);
  242.   },
  243.  
  244.   onSyncDelay: function WeaveWin_onSyncDelay(subject, data) {
  245.     // basically, we want to just inform users that stuff is going to take a while
  246.     let title = this._stringBundle.getString("error.sync.no_node_found.title");
  247.     let description = this._stringBundle.getString("error.sync.no_node_found");
  248.     let notification = new Weave.Notification(title, description, null, Weave.Notifications.PRIORITY_INFO);
  249.     Weave.Notifications.replaceTitle(notification);
  250.     this._wasDelayed = true;
  251.   },
  252.  
  253.   onEngineStart: function WeaveWin_onEngineStart(subject, data) {
  254.     if (!this._allowSBUpdates)
  255.       return;
  256.  
  257.     let engine = subject == "clients" ? Weave.Clients : Weave.Engines.get(subject);
  258.     let engineName = engine.displayName;
  259.     let label = this._stringBundle.getFormattedString("syncing.label", [engineName]);
  260.     let button = document.getElementById("sync-menu-button");
  261.     button.setAttribute("label", label);
  262.   },
  263.  
  264.   openPrefs: function openPrefs() {
  265.     let pane = "paneWeaveServices";
  266.     switch (Weave.Svc.AppInfo.ID) {
  267.       case Weave.FIREFOX_ID:
  268.         openPreferences(pane);
  269.         break;
  270.  
  271.       case Weave.SEAMONKEY_ID:
  272.         goPreferences(pane);
  273.         break;
  274.     }
  275.   },
  276.  
  277.   doLogin: function WeaveWin_doLogout(event) {
  278.     setTimeout(function() Weave.Service.login(), 0);
  279.   },
  280.  
  281.   doLogout: function WeaveWin_doLogout(event) {
  282.     setTimeout(function() Weave.Service.logout(), 0);
  283.   },
  284.  
  285.   doSync: function WeaveWin_doSync(event) {
  286.     setTimeout(function() Weave.Service.sync(), 0);
  287.   },
  288.  
  289.   doOpenActivityLog: function WeaveWin_doOpenActivityLog(event) {
  290.     let logFile = Weave.Svc.Directory.get("ProfD", Ci.nsIFile);
  291.     logFile.append("weave");
  292.     logFile.append("logs");
  293.     logFile.append("verbose-log.txt");
  294.  
  295.     let url = Weave.Svc.IO.newFileURI(logFile).spec;
  296.     window.openUILinkIn(url, "tab");
  297.   },
  298.  
  299.   doPopup: function WeaveWin_doPopup(event) {
  300.     this._updateLastSyncItem();
  301.  
  302.     let loginItem = document.getElementById("sync-loginitem");
  303.     let logoutItem = document.getElementById("sync-logoutitem");
  304.     let syncItem = document.getElementById("sync-syncnowitem");
  305.  
  306.     // Don't allow "login" to be selected in some cases
  307.     let offline = Weave.Svc.IO.offline;
  308.     let delayed = Weave.Status.service == Weave.STATUS_DELAYED;
  309.     let locked = Weave.Service.locked;
  310.     let pbEnabled = Weave.Svc.Private.privateBrowsingEnabled;
  311.     let noUser = Weave.Service.username == "";
  312.     let notReady = offline || delayed || locked || pbEnabled || noUser;
  313.     loginItem.setAttribute("disabled", notReady);
  314.     logoutItem.setAttribute("disabled", notReady);
  315.  
  316.     // Don't allow "sync now" to be selected in some cases
  317.     let loggedIn = Weave.Service.isLoggedIn;
  318.     let noNode = Weave.Status.sync == Weave.NO_SYNC_NODE_FOUND;
  319.     let disableSync = notReady || !loggedIn || noNode || pbEnabled;
  320.     syncItem.setAttribute("disabled", disableSync);
  321.  
  322.     // Only show one of login/logout
  323.     loginItem.setAttribute("hidden", loggedIn);
  324.     logoutItem.setAttribute("hidden", !loggedIn);
  325.   },
  326.  
  327.   onNotificationAdded: function WeaveWin_onNotificationAdded() {
  328.     document.getElementById("sync-notifications-button").hidden = false;
  329.     let notifications = Weave.Notifications.notifications;
  330.     let priority = 0;
  331.     for (let i = 0;i < notifications.length;i++)
  332.       priority = Math.max(notifications[i].priority, priority);
  333.  
  334.     let image = priority >= Weave.Notifications.PRIORITY_WARNING ?
  335.                 "chrome://global/skin/icons/warning-16.png" :
  336.                 "chrome://global/skin/icons/information-16.png";
  337.     document.getElementById("sync-notifications-button").image = image;
  338.   },
  339.  
  340.   onNotificationRemoved: function WeaveWin_onNotificationRemoved() {
  341.     if (Weave.Notifications.notifications.length == 0)
  342.       document.getElementById("sync-notifications-button").hidden = true;
  343.   },
  344.  
  345.   _updateLastSyncItem: function WeaveWin__updateLastSyncItem() {
  346.     let lastSync = Weave.Svc.Prefs.get("lastSync");
  347.     if (!lastSync)
  348.       return;
  349.  
  350.     let lastSyncItem = document.getElementById("sync-lastsyncitem");
  351.     if (!lastSyncItem)
  352.       return;
  353.  
  354.     // Show the day-of-week and time (HH:MM) of last sync
  355.     let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
  356.     let lastSyncLabel =
  357.       this._stringBundle.getFormattedString("lastSync.label", [lastSyncDate]);
  358.     lastSyncItem.setAttribute("label", lastSyncLabel);
  359.     lastSyncItem.setAttribute("hidden", "false");
  360.   },
  361.  
  362.   onMenuPopupHiding: function WeaveWin_onMenuPopupHiding() {
  363.     var menuPopup = document.getElementById('sync-menu-popup');
  364.     var menu = document.getElementById('sync-menu');
  365.  
  366.     // If the menu popup isn't on the Tools > Sync menu, then move the popup
  367.     // back onto that menu so the popup appears when the user selects the menu.
  368.     // We'll move the popup back to the menu button when the user clicks on
  369.     // the menu button.
  370.     if (menuPopup.parentNode != menu)
  371.       menu.appendChild(menuPopup);
  372.   },
  373.  
  374.   onMenuButtonMouseDown: function WeaveWin_onMenuButtonMouseDown() {
  375.     var menuPopup = document.getElementById('sync-menu-popup');
  376.     var menuButton = document.getElementById("sync-menu-button");
  377.  
  378.     // If the menu popup isn't on the menu button, then move the popup onto
  379.     // the button so the popup appears when the user clicks the button.  We'll
  380.     // move the popup back to the Tools > Sync menu when the popup hides.
  381.     if (menuPopup.parentNode != menuButton)
  382.       menuButton.appendChild(menuPopup);
  383.  
  384.     menuPopup.openPopup(menuButton, "before_start", 0, 0, true);
  385.   }
  386. };
  387.  
  388. let gWeaveWin;
  389.  
  390. window.addEventListener("load", function(e) { gWeaveWin = new WeaveWindow(); }, false);
  391.